home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / gfx / conv / dltogl.lha / dltogl.c < prev    next >
C/C++ Source or Header  |  1993-08-30  |  8KB  |  414 lines

  1. /*
  2.  * dltogl.c -- convert .DL animations into .GL animations.
  3.  *
  4.  * usage: dltogl file.dl [file.gl]
  5.  *
  6.  * If no .gl file is specified, the images and control file will be
  7.  * written to separate files.  The control file will always be "dl.txt",
  8.  * the images "clpN.clp" and a palette file called "palette.pic".
  9.  *
  10.  * Author:
  11.  *    George Phillips
  12.  *    <phillips@cs.ubc.ca>
  13.  */
  14.  
  15. #include <string.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include "dltogl_protos.h"
  19.  
  20. #define FOW    "wb"
  21.  
  22. FILE*    gl;
  23. int        gl_fileno;
  24.  
  25. FILE* file_open();
  26. int file_close();
  27.  
  28. #define isneg16(x)    ((x) & 0x8000)
  29. #define neg16(x)    ((~(x) + 1) & 0x7fff)
  30.  
  31. main(argc, argv)
  32. int        argc;
  33. char*    argv[];
  34. {
  35.     unsigned int i, j;
  36.     FILE* fp;
  37.     int num_scrn;
  38.     int ctl_len;
  39.     int format;
  40.     static char title[21];
  41.     static char author[21];
  42.     static unsigned char pal[256*3];
  43.     unsigned char* screen;
  44.     static unsigned char halfscreen[160*100];
  45.     static char fname[32];
  46.     int picnum;
  47.     int images_per_screen;
  48.     FILE* ctl;
  49.     int fx, fy;
  50.     int* cmd;
  51.     int labelpos;
  52.     int cmdnum;
  53.  
  54.     if (argc != 2 && argc != 3)
  55.         die("usage: dltogl file.dl [file.gl]");
  56.  
  57.     if (!(fp = fopen(argv[1], "rb"))) {
  58.         fprintf(stderr, "dltogl: can't open %s\n", argv[1]);
  59.         exit(1);
  60.     }
  61.  
  62.     gl = 0;
  63.     gl_fileno = 0;
  64.     if (argc == 3 && !(gl = fopen(argv[2], FOW))) {
  65.         fprintf(stderr, "dltogl: can't open %s for writing\n", argv[2]);
  66.         exit(1);
  67.     }
  68.  
  69.     if (fgetc(fp) != 2)
  70.         die("dltogl: only version 2 files can be handled");
  71.  
  72.     switch (format = fgetc(fp)) {
  73.     case 0:
  74.         fx = fy = 0;
  75.         images_per_screen = 1;
  76.         break;
  77.     case 1:
  78.         fx = 80;
  79.         fy = 50;
  80.         images_per_screen = 4;
  81.         break;
  82.     default:
  83.         die("dltogl: only large and medium formats are handled");
  84.         break;
  85.     }
  86.  
  87.     title[20] = author[20] = 0;
  88.     for (i = 0; i < 20; i++)
  89.         title[i] = fgetc(fp) ^ 255;
  90.  
  91.     for (i = 0; i < 20; i++)
  92.         author[i] = fgetc(fp) ^ 255;
  93.  
  94.     for (i = 0; i < 20; i++) {
  95.         if ((unsigned char)title[i] == 255) title[i] = 0;
  96.         if ((unsigned char)author[i] == 255) author[i] = 0;
  97.     }
  98.  
  99.     num_scrn = fgetc(fp);
  100.     ctl_len = fgetc(fp);
  101.  
  102.     if (!(cmd = (int*)malloc(ctl_len * sizeof(int))))
  103.         die("dltogl: out of memory");
  104.  
  105.     gl_numfiles(num_scrn * images_per_screen + 1 + 1);
  106.  
  107.     /* mebbe this is the border colour? */
  108.     for (i = 0; i < 3; i++)
  109.         fgetc(fp);
  110.  
  111.     for (i = 0; i < 256; i++) {
  112.         pal[i*3] = fgetc(fp);
  113.         pal[i*3+1] = fgetc(fp);
  114.         pal[i*3+2] = fgetc(fp);
  115.     }
  116.  
  117.     if (!(screen = malloc(320 * 200)))
  118.         die("dltogl: not enough memory.");
  119.  
  120.     memset(screen, 0, 320 * 200);
  121.     writepic(screen, 320, 200, "palette.pic", pal);
  122.  
  123.     picnum = 0;
  124.     for (j = 0; j < num_scrn; j++) {
  125.         fread(screen, 320 * 200, 1, fp);
  126.         switch (format) {
  127.         case 0: /* large */
  128.             sprintf(fname, "clp%d.clp", picnum++);
  129.             writepic(screen, 320, 200, fname, (unsigned char*)0);
  130.             break;
  131.         case 1: /* medium */
  132.             for (i = 0; i < 4; i++) {
  133.                 unsigned char*    src;
  134.                 unsigned char*    dst;
  135.                 int                row;
  136.                 int                col;
  137.  
  138.                 sprintf(fname, "clp%d.clp", picnum++);
  139.                 src = screen + (i % 2) * 160 + (i / 2) * 100 * 320;
  140.                 dst = halfscreen;
  141.                 for (row = 0; row < 100; row++) {
  142.                     for (col = 0; col < 160; col++)
  143.                         *dst++ = *src++;
  144.                     src += 160;
  145.                 }
  146.                 writepic(halfscreen, 160, 100, fname, (unsigned char*)0);
  147.             }
  148.         }
  149.     }
  150.  
  151.     ctl = file_open("dl.txt", FOW);
  152.  
  153.     fprintf(ctl, "; This GL file was converted from DL format by dltogl\r\n");
  154.     fprintf(ctl, "; Title:  %s\r\n", title);
  155.     fprintf(ctl, "; Author: %s\r\n", author);
  156.     /* could print all the other keeno information */
  157.  
  158.     fprintf(ctl, "video l\r\n");
  159.     fprintf(ctl, "pload palette,1\r\n");
  160.     fprintf(ctl, "palette 1\r\n");
  161.     fprintf(ctl, "pfree 1\r\n");
  162.     for (i = 0; i < num_scrn * images_per_screen; i++)
  163.         fprintf(ctl, "cload clp%d,%d\r\n", i, i + 1);
  164.  
  165.     for (i = 0; i < ctl_len; i++) {
  166.         j = fgetc(fp);
  167.         j += fgetc(fp) << 8;
  168.         cmd[i] = j;
  169.     }
  170.  
  171.     labelpos = 0;
  172.     if (isneg16(cmd[ctl_len - 1])) {
  173.         labelpos = neg16(cmd[ctl_len - 1]) + 1;
  174.         ctl_len--;    /* ignore that last command */
  175.     }
  176.  
  177.     for (i = 0, cmdnum = 0; i < ctl_len; i++, cmdnum++) {
  178.         if (cmdnum == labelpos)
  179.             fprintf(ctl, "forever:\r\n");
  180.         if (isneg16(cmd[i])) {
  181.             i++;
  182.             fprintf(ctl, "waitkey %d\r\n", cmd[i]);
  183.         }
  184.         else
  185.             fprintf(ctl, "putup %d,%d,%d,10\r\n", fx, fy, cmd[i] + 1);
  186.     }
  187.     fprintf(ctl, "goto forever\r\n");
  188.     fputc(26, ctl);
  189.     file_close(ctl);
  190.  
  191.     fclose(fp);
  192.  
  193.     if (gl)
  194.         fclose(gl);
  195.  
  196.     exit(0);
  197. }
  198.  
  199. void die(s)
  200. char*s;
  201. {
  202.     fprintf(stderr,"%s\n",s);
  203.     exit(1);
  204. }
  205.  
  206. #define BLOCKSIZE    (8192)
  207.  
  208. void writepic(pixel, width, height, filename, cmap)
  209. unsigned char* pixel;
  210. int    width;
  211. int    height;
  212. char* filename;
  213. unsigned char* cmap;
  214. {
  215.     FILE*    fp;
  216.     unsigned int i;
  217.     static unsigned char buf[BLOCKSIZE];
  218.     unsigned char* p;
  219.     int row, col;
  220.  
  221.     fp = file_open(filename, FOW);
  222.  
  223.     /* write header */
  224.     writeshort(fp, 0x1234);    /* magic number */
  225.     writeshort(fp, width);
  226.     writeshort(fp, height);
  227.     writeshort(fp, 0);
  228.     writeshort(fp, 0);
  229.     fputc(8, fp);                        /* bits per pixel */
  230.     fputc(0xff, fp);                    /* byte here is always 255 */
  231.     fputc('L', fp);                        /* video mode */
  232.     if (cmap) {
  233.         writeshort(fp, 4);        /* extra information descriptor */
  234.         writeshort(fp, 768);    /* extra information length */
  235.         fwrite(cmap, 768, 1, fp);
  236.     }
  237.     else {
  238.         writeshort(fp, 0);
  239.         writeshort(fp, 0);
  240.     }
  241.  
  242.     /* number of packed blocks in file */
  243.     writeshort(fp, ((long)width * height + BLOCKSIZE - 1) / BLOCKSIZE);
  244.  
  245.     i = 0;
  246.     for (row = height - 1; row >= 0; row--) {
  247.         p = pixel + row * width;
  248.         for (col = 0; col < width; col++) {
  249.             buf[i++] = *p++;
  250.             if (i == BLOCKSIZE) {
  251.                 outpackblock(fp, buf, i);
  252.                 i = 0;
  253.             }
  254.         }
  255.     }
  256.     if (i > 0)
  257.         outpackblock(fp, buf, i);
  258.  
  259.     file_close(fp);
  260. }
  261.  
  262. void outpackblock(fp, buf, len)
  263. FILE*    fp;
  264. char*    buf;
  265. int    len;
  266. {
  267.     static char    packbuf[BLOCKSIZE * 4 - 1];    /* overkill */
  268.     int    packlen;
  269.  
  270.     packlen = packblock(buf, packbuf, len);
  271.     fwrite(packbuf, packlen, 1, fp);
  272. }
  273.  
  274. int packblock(src, dest, len)
  275. char*    src;
  276. char*    dest;
  277. int        len;
  278. {
  279.     unsigned char*    s;
  280.     unsigned char*    r;
  281.     unsigned char*    d;
  282.     static int    overhead[256];
  283.     int    i;
  284.     int    esc;
  285.     int    escpresent;
  286.     int    minover;
  287.     int    packlen;
  288.  
  289.     for (i = 0; i < 256; i++)
  290.         overhead[i] = 0;
  291.  
  292.     /* do first pass to find optimal esc byte */
  293.     for (s = src; s < src + len; s = r) {
  294.         for (r = s; *r == *s && r < src + len; r++)
  295.             ;
  296.         if (r - s < 4)
  297.             overhead[*s]++;
  298.     }
  299.  
  300.     minover = len + 1;
  301.     for (i = 0; i < 256; i++) {
  302.         if (overhead[i] < minover) {
  303.             minover = overhead[i];
  304.             esc = i;
  305.         }
  306.     }
  307.     escpresent = overhead[esc] == 0;
  308.  
  309.     /* now run-length encode on the second pass */
  310.  
  311.     d = dest + 5;
  312.     for (s = src; s < src + len; s = r) {
  313.         for (r = s; *r == *s && r < src + len; r++)
  314.             ;
  315.         if (r - s < 4 && (!escpresent || *s != esc)) {
  316.             while (s < r)
  317.                 *d++ = *s++;
  318.         }
  319.         else {
  320.             if (r - s > 255) {
  321.                 *d++ = esc;
  322.                 *d++ = 0;
  323.                 *d++ = (r - s) & 0xff;
  324.                 *d++ = ((r - s) >> 8) & 0xff;
  325.                 *d++ = *s++;
  326.             }
  327.             else {
  328.                 *d++ = esc;
  329.                 *d++ = r - s;
  330.                 *d++ = *s++;
  331.             }
  332.         }
  333.     }
  334.  
  335.     packlen = d - dest;
  336.  
  337.     /* fill in the block header */
  338.  
  339.     *dest++ = packlen & 0xff;            /* packed block size */
  340.     *dest++ = ((packlen) >> 8) & 0xff;
  341.     *dest++ = len & 0xff;
  342.     *dest++ = (len >> 8) & 0xff;        /* unpacked block size */
  343.     *dest++ = esc;                        /* escape byte */
  344.  
  345.     return packlen;
  346. }
  347.  
  348. void writeshort(fp, s)
  349. FILE*    fp;
  350. int        s;
  351. {
  352.     fputc(s & 255, fp);
  353.     fputc((s >> 8) & 255, fp);
  354. }
  355.  
  356. void writelong(fp, l)
  357. FILE*    fp;
  358. long    l;
  359. {
  360.     fputc(l & 255, fp);
  361.     fputc((l >> 8) & 255, fp);
  362.     fputc((l >> 16) & 255, fp);
  363.     fputc((l >> 24) & 255, fp);
  364. }
  365.  
  366. long gl_eof;
  367. long gl_filestart;
  368.  
  369. void gl_numfiles(n)
  370. int    n;
  371. {
  372.     if (gl) {
  373.         fseek(gl, 0, 0);
  374.         writeshort(gl, n * 17);
  375.         gl_eof = 2 + n * 17;
  376.     }
  377. }
  378.  
  379. FILE* file_open(name, mode)
  380. char*    name;
  381. char*    mode;
  382. {
  383.     FILE*    fp;
  384.     char    fname[14];
  385.  
  386.     if (!gl) {
  387.         if (!(fp = fopen(name, mode))) {
  388.             fprintf(stderr, "dltogl: can't open %s\n", name);
  389.             exit(1);
  390.         }
  391.         return fp;
  392.     }
  393.  
  394.     fseek(gl, 2 + gl_fileno++ * 17, 0);
  395.     writelong(gl, gl_eof);
  396.     memset(fname, 0, 13);
  397.     strcpy(fname, name);
  398.     fwrite(fname, 13, 1, gl);
  399.     fseek(gl, gl_filestart = gl_eof + 4, 0);
  400.     return gl;
  401. }
  402.  
  403. int file_close(fp)
  404. FILE*    fp;
  405. {
  406.     if (!gl)
  407.         return fclose(fp);
  408.  
  409.     gl_eof = ftell(gl);
  410.     fseek(gl, gl_filestart - 4, 0);
  411.     writelong(gl, gl_eof - gl_filestart);
  412. }
  413.  
  414.